﻿using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using System.Collections.Generic;
using System.Data;

namespace SPWorks.ControlTemplates.SPWorks
{
    public partial class ListItemPermission : UserControl
    {
        public static string[] listItems;
        public static SPList list;
        List<SPUser> loadedUsers = new List<SPUser>();
        List<SPRoleDefinition> roles = new List<SPRoleDefinition>();
        

        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                if (!IsPostBack)
                {
                    LoadPermissions();
                    LoadUsers();
                    
                    SPWeb spweb = SPContext.Current.Web;
                    
                    if (Request.QueryString.Count > 0)
                    {
                        Guid listGuid = new Guid(Request.QueryString["list"].ToString());
                        list = spweb.Lists[listGuid];
                        listItems = Request.QueryString["itemIds"].ToString().Split(";".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                        lblLibrary.Text = list.Title;
                        lblDocuments.Text = string.Empty;
                        foreach (string listItem in listItems)
                        {
                            lblDocuments.Text += list.Items.GetItemById(Convert.ToInt32(listItem)).Title + ",";
                        }
                    }
                    CreateTable();
                }
            }
            catch (Exception ex)
            {
                Label3.Text = ex.Message + " : " + ex.Source + "<br/>Load";
            }
        }

        private void LoadUsers()
        {
            SPWeb web = SPContext.Current.Web;

            ddlUserGroups.Items.Clear();
            loadedUsers.Clear();

            ddlUserGroups.Items.Add("All");
            foreach (SPUser user in web.Users)
            {
                if (!loadedUsers.Contains(user))
                    loadedUsers.Add(user);
            }
            foreach (SPGroup grp in web.Groups)
            {
                ddlUserGroups.Items.Add(grp.Name);
                foreach (SPUser user in grp.Users)
                {
                    if (!loadedUsers.Contains(user))
                        loadedUsers.Add(user);
                }
            }
        }

        private void LoadGroupedUsers()
        {
            SPWeb web = SPContext.Current.Web;
            loadedUsers.Clear();

            if (ddlUserGroups.SelectedItem.Text == "All")
            {
                foreach (SPUser user in web.Users)
                {
                    if(!loadedUsers.Contains(user))
                        loadedUsers.Add(user);
                }
                foreach (SPGroup grp in web.Groups)
                {
                    ddlUserGroups.Items.Add(grp.Name);
                    foreach (SPUser user in grp.Users)
                    {
                        if (!loadedUsers.Contains(user))
                            loadedUsers.Add(user);
                    }
                }
            }
            else
            {

                SPGroup grp = web.Groups[ddlUserGroups.SelectedItem.Text];
                foreach (SPUser user in grp.Users)
                {
                    if (!loadedUsers.Contains(user))
                        loadedUsers.Add(user);
                }
            }
        }

        private void CreateTable()
        {
            DataTable dt = new DataTable();

            List<object> rowData = new List<object>();
            dt.Columns.Add("User\\Role");
            dt.Columns.Add("SA");
            foreach (SPRoleDefinition role in roles)
            {
                dt.Columns.Add(role.Name, typeof(bool));                
            }

            foreach (SPUser user in loadedUsers)
            {
                DataRow dr = dt.NewRow();
                dr["User\\Role"] = user.Name;
                if(user.IsSiteAdmin)
                    dr["SA"] = "*";
                else
                    dr["SA"] = " ";

                foreach (SPRoleDefinition role in roles)
                {
                    dr[role.Name] = false;
                }
                dt.Rows.Add(dr);
            }

            ViewState["data"] = dt;
            ReBindData();
        }

        private void LoadPermissions()
        {
            SPWeb web = SPContext.Current.Web;
            SPRoleDefinitionCollection roleColl = web.RoleDefinitions;
            foreach (SPRoleDefinition role in roleColl)
            {
                roles.Add(role);
            }
        }

        protected void ddlUserGroups_SelectedIndexChanged(object sender, EventArgs e)
        {
            LoadGroupedUsers();
            LoadPermissions();
            CreateTable();
        }

        protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
        {
            grdPermissions.EditIndex = e.NewEditIndex;
            ReBindData();
        }

        protected void GridView1_RowUpdated(object sender, GridViewUpdatedEventArgs e)
        {

        }

        protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
        {
            DataTable dt = (DataTable)ViewState["data"];
            GridViewRow row = grdPermissions.Rows[e.RowIndex];

            for (int i = 3; i < row.Cells.Count; i++)
            {
                dt.Rows[row.DataItemIndex][i-1] = ((CheckBox)(row.Cells[i].Controls[0])).Checked;
            }

            grdPermissions.EditIndex = -1;

            ReBindData();
        }

        protected void GridView1_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
        {
            grdPermissions.EditIndex = -1;
            ReBindData();
        }

        private void ReBindData()
        {
            grdPermissions.DataSource = (DataTable)ViewState["data"];
            grdPermissions.DataBind();
        }

        protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            
        }

        protected void btnApplyPermission_Click(object sender, EventArgs e)
        {
            SPWeb web = SPContext.Current.Web;
            LoadGroupedUsers();
            LoadPermissions();
            for (int i = 0; i < listItems.Length; i++)
            {
                SPListItem litem = list.GetItemById(Convert.ToInt32(listItems[i]));
                SPRoleAssignmentCollection SPRoleAssColn = litem.RoleAssignments;
                if (!litem.HasUniqueRoleAssignments)
                {
                    litem.BreakRoleInheritance(false);
                }
                for (int j = SPRoleAssColn.Count - 1; j >= 0; j--)
                {
                    SPRoleAssColn.Remove(j);
                }
            }

            try
            {
                string str = string.Empty;

                DataTable dt = (DataTable)ViewState["data"];

                web.AllowUnsafeUpdates = true;
                for (int r = 0; r < dt.Rows.Count; r++)
                {
                    for (int c = 2; c < dt.Columns.Count; c++)
                    {
                        if ((bool)dt.Rows[r][c])
                        {
                            str += dt.Rows[r][0].ToString() + " : " + dt.Columns[c].Caption + " : " + dt.Rows[r][c].ToString() + "<br/>";
                            string tUsername = dt.Rows[r][0].ToString();
                            string tRolename = dt.Columns[c].Caption;

                            for (int i = 0; i < listItems.Length; i++)
                            {
                                SPListItem litem = list.GetItemById(Convert.ToInt32(listItems[i]));

                                SPUser user = loadedUsers.Find(usr => usr.Name == tUsername);
                                SPRoleDefinition roleDefinition = roles.Find(sprd => sprd.Name == tRolename);
                                SPRoleAssignment roleAssignment = new SPRoleAssignment(user);// user.LoginName,user.Email,user.Name,user.Notes);
                                
                                if (!roleAssignment.RoleDefinitionBindings.Contains(roleDefinition))
                                    roleAssignment.RoleDefinitionBindings.Add(roleDefinition);

                                //Check inheritance
                                litem.RoleAssignments.Add(roleAssignment);
                                litem.Update();
                            }
                        }
                    }
                    str += "<br/>";
                }
                web.AllowUnsafeUpdates = false;
                Label3.Text = "Permission Set : <br/>" + str;
            }
            catch (Exception ex)
            {
                Label3.Text = ex.Message + "<br/>";
            }
        }

        public static void CreatePermissions(SPWeb theWeb, SPListItem ListItem, string loginName, string roleName, string permissionLevel)
        {
            try
            {
                theWeb = new SPSite(theWeb.Site.ID).OpenWeb(theWeb.ID);
                theWeb.AllowUnsafeUpdates = true;

                ListItem = theWeb.Lists[ListItem.ParentList.ID].GetItemById(ListItem.ID);

                SPRoleAssignment roleAssignment = new SPRoleAssignment(loginName, "", roleName, "");

                SPRoleDefinition RoleDefinition = theWeb.RoleDefinitions[permissionLevel];

                if (!roleAssignment.RoleDefinitionBindings.Contains(RoleDefinition))
                    roleAssignment.RoleDefinitionBindings.Add(RoleDefinition);

                //Check inheritance
                if (!ListItem.HasUniqueRoleAssignments)
                {
                    ListItem.BreakRoleInheritance(false);
                }

                ListItem.RoleAssignments.Add(roleAssignment);

                ListItem.Update();

            }
            catch (Exception ex)
            {
                
            }
        }
    }
}
